<template>
    <div id="container" ref="editor" class="monaco-editor-container"></div>
</template>

<script lang="ts" setup>
import { onMounted } from 'vue';
import * as monaco from 'monaco-editor';
import { toRaw } from 'vue';
import { ref } from 'vue';
import { watchEffect } from 'vue';

// 定义组件属性及类型
interface Props {
    language: string;
    code: string;
    // 定义一个接收函数类型的组件属性
    handleChange: (v:string) => void;
}

// 声明组件的属性，并设置默认值
const props = withDefaults(defineProps<Props>(), {
    language: 'java',
    code: '',
    handleChange: (v:string) => {
        console.log('v', v);   
    }
})

const codeEditor = ref();

// 在组件挂载后初始化 Monaco Editor
onMounted(() => {
    // 创建 Monaco Editor 实例
    const codeElement = document.getElementById('container')
    if (!codeElement) {
        throw Error('编辑器对象不存在')
    }
    // 你可以在这里添加更多的配置和事件监听
    codeEditor.value = monaco.editor.create(codeElement, {
        value: '', // 初始代码
        language: 'java', // 初始语言
        theme: 'vs-dark', // 主题
        automaticLayout: true, // 允许自动调整布局
    });

    // 编辑器内容改变监听函数
    codeEditor.value.onDidChangeModelContent(()=> {
        // 获取编辑器内容
        const value = toRaw(codeEditor.value).getValue();
        // 当编辑器内的值改变的时候，调用父组件传递过来的方法，将编辑器的值传递给父组件中的 code 响应式变量
        props.handleChange(value);
    });    
});

// 监听语言的变动，修改编辑器语言
watchEffect(() => {
    console.log('watchEffect 函数', props.language);
    // 判断编辑器是否存在，存在才修改语言
    if (!codeEditor.value) {
        return;
    }
    monaco.editor.setModelLanguage(
        // 踩坑一定要使用toRaw：获取一个响应式对象的原始值
        toRaw(codeEditor.value).getModel(),
        props.language
    );
})

// 监听变量
// watch(() => props.language, () => {
//     console.log('watch', props.language);
// })

</script>

<style lang="less" scoped>
.monaco-editor-container {
    height: 75vh;
}
</style>
